import { reactive, inject, provide } from 'vue';
import { ConsoleLogger } from '@/utils/debug-log';
import { menuData, introduce } from '@/domain/dataBoard/hooks/menuInfo';
import { getMenuAuthority } from '../api/authority';
import { MenuItem } from '../types/authority';
import { longClassData, shortClassData, RouterType } from '@/project/dataBoard/router';

const console = new ConsoleLogger('菜单数据');
const useStateSymbol = Symbol('useState store');

export interface IMenuState {
  menuData: Array<any>;
}

export interface IMenuMenuStoreFn {
  (): IUseMenuStore;
}

export interface IUseMenuStore {
  state: IMenuState;
  menuAuthority: (param: { userCode: string }) => void;
}

/**
 * 深度遍历
 */
function depthTraverse(root: MenuItem[], callback: (param: MenuItem) => void) {
  let nodeStack: MenuItem[] = []; // 栈
  root.forEach((item) => {
    nodeStack.push(item); // 根节点入栈
  });

  while (nodeStack.length) {
    const curNode = nodeStack.pop();
    if (!curNode) break;
    callback(curNode);
    const childNodes = curNode.children;
    if (childNodes?.length) {
      // 子节点入栈
      childNodes.forEach((child) => {
        nodeStack.push(child);
      });
    }
  }
}

export const useMenuProvide: () => IUseMenuStore = () => {
  const state = reactive<IMenuState>({
    menuData: menuData
  });

  // 获取菜单权限
  const menuAuthority = ({ userCode }: { userCode: string }) => {
    getMenuAuthority({ userCode, systemLid: 2 }).then(({ data }) => {
      const menuList: string[] = [];
      depthTraverse(data, (param) => {
        menuList.push(param.url);
      });
      // 过滤 menuData
      let menuDataCopy = (introduce as RouterType[]).concat([
        {
          chname: '长期班',
          name: 'longClass',
          icon: 'iconfont icon-icon_long',
          path: `/longClass`,
          children: longClassData
        },
        {
          chname: '短期班',
          name: 'shortRach',
          icon: 'iconfont icon-icon_short',
          path: `/shortClass`,
          children: shortClassData
        }
      ]);
      menuDataCopy = menuDataCopy.filter((child) => {
        if (child.children) {
          child.children = child.children.filter((item: { path: string }) => menuList.includes(item.path));
        }
        return menuList.includes(child.path);
      });
      state.menuData = menuDataCopy;
    });
  };

  const store: IUseMenuStore = {
    state,
    menuAuthority
  };

  provide(useStateSymbol, { ...store });

  return store;
};

/**
 *  * useMenuStore 用户hooks.
 * @function
 * @returns store extend IUseMenuStore
 */
export const useMenuStore: IMenuMenuStoreFn = () => {
  const store: IUseMenuStore = inject(useStateSymbol) as IUseMenuStore;
  return store;
};
